import type { FormInstance } from 'ant-design-vue';
import { useFormBeforeSubmit, useFormSubmit, useFormSubmitFunc } from './useFormSubmit';
import { ref, toRaw, watch } from 'vue';
import type { ApiResponseSuccess } from 'axios';
import type { RowKey } from '@ykst/components';

export interface BaseFormType {
  id?: RowKey;
  [key: string | number]: any;
}

export interface useFormEmits {
  (e: 'success', res: ApiResponseSuccess, formValue: any): void;
  (e: 'update:open', value: boolean): void;
}

export interface useFormProps<T extends BaseFormType = any> {
  /** modal的open状态 */
  open?: boolean;
  /** 表单默认值 */
  defaultValue?: T;
  /** 表单是否是编辑状态 */
  edit?: boolean;
  /** modal的title */
  title?: string;
}

export interface useFormSubmitParams<D, T = D> {
  /** 表单提交函数 */
  requestFunc: useFormSubmitFunc<D>;
  /** 表单提交函数运行之前的函数，可以在这里处理请求参数 */
  beforeSubmit?: useFormBeforeSubmit<D, T>;
  /** 操作的标题，如：设备停机记录 */
  actionTitle?: string;
}

/**
 * 通用的表单编辑和新增提交函数
 * @param props defineProps<useFormProps>()定义的props
 * @param emit defineEmits<useFormEmits>()定义的emit
 * @param option useFormSubmit要求提供的requestFunc、beforeSubmit、actionTitle
 * @description 泛型说明
 * - D： requestFunc的ApiFuncData.data类型，
 * - 泛型FD： 表单的data类型，默认和D一样，大部分情况FD和D不一样，
 */
export function useForm<D extends BaseFormType = any, T = D>(
  props: useFormProps,
  emit: useFormEmits,
  option: useFormSubmitParams<D, T>,
) {
  const visible = ref(props.open);
  const formValue = ref<T>(props.defaultValue ?? {});
  const formRef = ref<FormInstance>();
  const { loading, editSubmit, addSubmit, onConfirmSubmit } = useFormSubmit(
    option.requestFunc,
    option.beforeSubmit,
    option.actionTitle,
  );
  watch(
    () => props.open,
    () => {
      if (props.open !== visible.value) {
        visible.value = props.open;
      }
    },
  );

  watch(visible, () => {
    if (props.open !== visible.value) {
      emit('update:open', visible.value ?? false);
    }
    if (visible.value === false) {
      // 重置表单并且清空表单数据
      formRef.value?.resetFields();
      formValue.value = { ...(props.defaultValue || {}) };
      loading.value = false;
    }
  });

  watchEffect(() => {
    formValue.value = { ...(props.defaultValue || {}) };
  });
  // 取消编辑
  function onCancel() {
    visible.value = false;
    formRef.value?.clearValidate();
    formRef.value?.resetFields();
  }

  /**
   * 提交编辑 不需要验证
   * @param closeForm 成功后是否关闭弹框，false 不关闭
   */
  async function submitJumpValidate(closeForm: boolean = true) {
    const value = toRaw(formValue.value);
    let res: ApiResponseSuccess;
    if (props.edit) {
      // @ts-ignore
      res = await editSubmit(value! as object, value.id);
    } else {
      // @ts-ignore
      res = await addSubmit(value!);
    }
    emit('success', res, value);
    if (closeForm !== false) {
      onCancel();
    } else {
      formRef.value?.clearValidate();
      formRef.value?.resetFields();
      formValue.value = { ...(props.defaultValue || {}) };
    }
  }

  /**
   * 提交编辑 需要验证
   * @param closeForm 成功后是否关闭弹框，false 不关闭
   */
  async function onSubmit(closeForm: boolean | any = true) {
    await formRef.value?.validate();
    return submitJumpValidate(closeForm);
  }

  // 表单布局
  const formItemLayoutWithOutLabel = {
    wrapperCol: { span: 19, offset: 5 },
  };
  const blockLabelLayout = {
    labelCol: { span: 24 },
    wrapperCol: { span: 24 },
  };
  const formItemLayout = {
    labelCol: { span: 5 },
    wrapperCol: { span: 19 },
  };

  // 表单名字
  const formTitle = computed(() => {
    const { title = '', edit } = props;
    return `${edit ? '编辑' : '新增'}${title}`;
  });
  return {
    visible,
    formValue,
    formRef,
    loading,
    formItemLayoutWithOutLabel,
    blockLabelLayout,
    formItemLayout,
    width: 560,
    formTitle,
    onCancel,
    onSubmit,
    onConfirmSubmit,
    submitJumpValidate,
  };
}
